package com.gulimall.auth.controller;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.constant.AuthServerConstant;
import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberResp;
import com.gulimall.auth.feign.MemberFeignService;
import com.gulimall.auth.service.LoginService;
import com.gulimall.auth.vo.UserLoginVo;
import com.gulimall.auth.vo.UserRegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author lhj
 * @Date 2024/2/29 20:43
 */
@Controller
public class LoginController {

    @Autowired
    LoginService loginService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    MemberFeignService memberFeignService;

    @PostMapping("/login")
    public String login(UserLoginVo userLoginVo, RedirectAttributes redirectAttributes, HttpSession session) {
        R result = memberFeignService.login(userLoginVo);
        if (result.getCode() != 0) {
            Map<String, String> error = new HashMap<>();
            error.put("msg", result.getData("msg", new TypeReference<String>(){}));
            redirectAttributes.addFlashAttribute("errors", error);
            return "redirect:http://auth.gulimall.com/login.html";
        }

        MemberResp memberResp = result.getData(new TypeReference<MemberResp>() {});
        session.setAttribute(AuthServerConstant.LOGIN_USER, memberResp);

        return "redirect:http://gulimall.com";
    }

    /**
     * 用户注册接口
     * @param userRegisterVo 用户实体
     * @param bindingResult 错误信息
     * @param redirectAttributes 域模型
     * @return string
     */
    @PostMapping(value = "/register")
    public String register(@Valid UserRegisterVo userRegisterVo, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            Map<String, String> errorMap = fieldErrors.stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            redirectAttributes.addFlashAttribute("errors", errorMap);
            return "redirect:http://auth.gulimall.com/register.html";
        }

        String redisKey = (AuthServerConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getPhone());

        String cacheCode = stringRedisTemplate.opsForValue().get(redisKey);
        Map<String, String> cacheMap = new HashMap<>();
        //校验验证码是否存在
        if (StringUtils.isEmpty(cacheCode)) {
            cacheMap.put("code", BizCodeEnum.SMS_CACHE_CODE_EXPIRED.getCode() + "");
            cacheMap.put("msg", BizCodeEnum.SMS_CACHE_CODE_EXPIRED.getMsg());
            redirectAttributes.addFlashAttribute("errors", cacheMap);
            return "redirect:http://auth.gulimall.com/register.html";
        }

        //验证码校验失败
        String code = cacheCode.split("_")[0];
        if (!userRegisterVo.getCode().equals(code)) {
            cacheMap.put("code", BizCodeEnum.SMS_CACHE_CODE_CHECK_ERROR.getCode() + "");
            cacheMap.put("msg", BizCodeEnum.SMS_CACHE_CODE_CHECK_ERROR.getMsg());
            redirectAttributes.addFlashAttribute("errors", cacheMap);
            return "redirect:http://auth.gulimall.com/register.html";
        }

        //远程调用会员服务进行注册
        stringRedisTemplate.delete(redisKey);
        R result = memberFeignService.registerMember(userRegisterVo);
        if (result.getCode() != 0) {
            cacheMap.put("code", BizCodeEnum.MEMBER_REGISTER_MEMBER_ERROR.getCode() + "");
            cacheMap.put("msg", BizCodeEnum.MEMBER_REGISTER_MEMBER_ERROR.getMsg());
            redirectAttributes.addFlashAttribute("errors", cacheMap);
            return "redirect:http://auth.gulimall.com/register.html";
        }

        return "redirect://auth.gulimall.com/login.html";
    }

    /**
     * 发送短信功能
     * @param phone
     * @return
     */
    @ResponseBody
    @GetMapping(value = "/sms/sendCode")
    public R sendCode(@RequestParam(value = "phone") String phone) {
        return loginService.sendCode(phone);
    }

}
